// 导入缓存文件
import { ref, isReactive, toRefs } from 'vue'
import { changeElectronStoreData, getElectronStoreData, setElectronStoreData } from "@/utils/Electron.ts";
import type { PiniaPluginContext } from "pinia";

// 设置本地store缓存的key
const STORE_CACHE_KEY_PREFIX = "store_";

// Pinia添加方法
declare module "pinia" {
  export interface PiniaCustomProperties {
    // 通知主进程让所有窗口同步pinia的状态
    stateSync(): void;
  }
}

// 处理electron多窗口，pinia共享问题
export function shareStorePlugin({ store }: PiniaPluginContext) {
  // 初始化本地缓存版本
  const storeName: string = store.$id;
  // 初始化store
  initStore(store);
  // 重写状态同步方法
  store.stateSync = () => {
    updateStoreSync(stringify(store.$state), storeName);
  };

  // 监听数据同步修改
  window.api.on("pinia-store-set", (event: any, targetStoreName: string, jsonStr: string) => {
    console.log('检测到数据变化')
    // 监听到状态改变后，同步更新状态
    if (storeName === targetStoreName) {
      // 补充版本号是否重置标识
      const obj = JSON.parse(jsonStr);
      const keys = Object.keys(obj);
      const values = Object.values(obj);
      /// 更新各个key对应的值的状态
      for (let i = 0; i < keys.length; i++) {
        changeState(store.$state, keys[i], values[i]);
        console.log('nowState', store.$state)
      }
    }
  });
}

/**
 * 状态更新同步
 * @param stateJsonStr 序列化的状态修改字符串
 * @param storeName  修改的状态的名称
 */
function updateStoreSync(stateJsonStr: string, storeName: string) {
  // 通知主线程更新
  changeElectronStoreData(storeName, stateJsonStr)
  // 更新本地缓存的store
  setElectronStoreData(STORE_CACHE_KEY_PREFIX + storeName, stateJsonStr);
}

/**
 * 修改state的值
 * 补充 如果反序列化的字段是map类型，需要额外处理
 */
function changeState(state: any, key: any, value: any) {
  if (Array.isArray(value)) {
    state[key] = ref(value);
  } else if (value instanceof Map) {
    state[key] = ref(Object.fromEntries(value));
  } else if (typeof value === 'object' && value !== null) {
    state[key] = toRefs(value);
  } else {
    state[key] = value
  }
}

/**
 * 初始化状态对象
 * @param store
 */
function initStore(store: any) {
  const cacheKey = STORE_CACHE_KEY_PREFIX + store.$id;
  console.log(`${cacheKey} initStore`)
  // 从本地缓存中读取store的值
  const stateJsonStr = getElectronStoreData(cacheKey);
  stateJsonStr.then((res: string)=> {
    console.log(res)
    if (res) {
      const stateCache = JSON.parse(res);
      const keys = Object.keys(stateCache);
      const values = Object.values(stateCache);
      console.log(`${keys}`)
      console.log(`${values}`)
      /// 更新各个key对应的值的状态
      for (let i = 0; i < keys.length; i++) {
        changeState(store.$state, keys[i], values[i]);
      }
    }
  })
  
}

/**
 * 2023/07/03 自定义序列化方式， 处理ts中map类型/对象序列化后为 {} 的情况
 */
function stringify(obj: any): string {
  return JSON.stringify(cloneToObject(obj));
}

// 将字段包含map的对象转为json对象的格式
function cloneToObject(obj: any): any {
  let newObj: any = obj;
  if (obj instanceof Map) {
    return Object.fromEntries(obj);
  }
  if (obj instanceof Object) {
    newObj = {};
    const keys = Object.keys(obj);
    const values = Object.values(obj);
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      const value = values[i];
      newObj[key] = cloneToObject(value);
    }
  }
  if (obj instanceof Array) {
    newObj = [];
    for (let i = 0; i < obj.length; i++) {
      newObj[i] = cloneToObject(obj[i]);
    }
  }
  return newObj;
}

